import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// create an axios instance
const service = axios.create({
  baseURL: '/manage', // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 1000 * 60 // request timeout
})

const pendingRequest = new Map()

function generateReqKey(config) {
  const { method, url, params, data } = config
  return [method, url.indexOf('/manage/') < 0 ? '/manage' + url : url, JSON.stringify(params), JSON.stringify(data)].join('&')
}

function addPendingRequest(config) {
  const requestKey = generateReqKey(config)
  pendingRequest.set(requestKey, true)
}

function removePendingRequest(config) {
  const requestKey = generateReqKey(config)
  if (pendingRequest.has(requestKey)) {
    pendingRequest.delete(requestKey)
  }
}

// request interceptor
service.interceptors.request.use(
  config => {
    if (config.url.indexOf('utils/upload/image') === -1) {
      const requestKey = generateReqKey(config)
      if (pendingRequest.has(requestKey)) {
        return Promise.reject(new Error('系统繁忙，请稍后...'))
      }
      addPendingRequest(config) // 把当前请求添加到pendingRequest对象中
    }

    if (store.getters.token) {
      config.headers['Authorization'] = 'Bearer ' + getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  (response) => {
    if (response.config.url.indexOf('utils/upload/image') === -1) {
      let config = JSON.parse(JSON.stringify(response.config))
      config = Object.assign({}, config, { data: config.data ? JSON.parse(config.data) : config.data })
      removePendingRequest(config) // 从pendingRequest对象中移除请求
    }
    const res = response.data

    // blob类型直接生成
    if (Object.prototype.toString.call(res) === '[object Blob]') {
      // 判断对象是否为`[对象 Blob]`
      if (!res.type.includes('application/json')) {
        // `application/json` 特殊类型 (可能因为错误造成的)
        const url = window.URL.createObjectURL(
          new Blob([res], {
            type: response.headers['content-type']
          })
        )
        console.log('responseType========', response.headers)
        const link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        link.setAttribute(
          'download',
          decodeURI(response.headers['content-disposition'].match(/filename=(.*)/)[1])
        )
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        return
      } else {
        // blob数据与json数据互相转换
        const reader = new FileReader()
        reader.readAsText(res, 'utf-8')
        reader.onload = (e) => {
          const readerres = reader.result
          let parseObj = {}
          parseObj = JSON.parse(readerres)
          Message({
            message: parseObj.message,
            type: 'error',
            duration: 5 * 1000
          })
          return
        }
      }
    }
    if (res.code && res.code !== 200) {
      if (res.code === 403 || res.code === 400 || res.code === 500) {
        Message({
          message: res.message,
          type: 'error',
          duration: 5 * 1000
        })
      }
      if (res.code === 404) {
        Message({
          message: res.message,
          type: 'warning',
          duration: 5 * 1000
        })
      }
      if (res.code === 401) {
        MessageBox.confirm('你已经退出, 请重新登陆', '提示', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    if (error.config && error.config.url.indexOf('utils/upload/image') === -1) {
      let config = JSON.parse(JSON.stringify(error.config))
      config = Object.assign({}, config, { data: config.data ? JSON.parse(config.data) : config.data })
      removePendingRequest(config)
    }
    // 添加异常处理
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service
